home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
DESK
/
CORE
/
Desk
/
!Help
next >
Wrap
Text File
|
1996-09-11
|
8KB
|
242 lines
Desk release 3.00beta (06 Sep 1996)
•••••••••••••••••••••••••••••••••••
Introduction
————————————
This is a beta release of the Desk library.
Desk is a new version of the DeskLib library. The main changes are error
handling, names, the directory structure, and an extra build for module
code. There are also a few new functions and sub-libraries.
The reason for the new library is that it wasn't possible to update
DeskLib to use the new error handling while preserving backwards
compatibility.
I'm fully aware that releasing an incompatible version of a wildly used
library like DeskLib may be unpopular, but it was already proving
difficult to add certain types of code to DeskLib because of it's
primitive error handling, so making radical changes had to happen at
some stage.
Names
—————
Every function, variable, typedef etc etc name has been prefixed with
'Desk_'. Thus 'Desk_Event_Initialise', 'Desk_Wimp_Poll' etc.
This has been done so that Desk can be used with other libraries without
name-clashes. For example, DeskLib's Wimp_ veneers clash badly with the
#defines used by OSLib, RISC _OSLib and Acorn's "swis.h" etc.
Also, the new error-handling means that Desk functions behave slightly
differently from the equivalent DeskLib ones (eg they don't return an
error code), so the names have to be different.
The new names are 5 characters longer which might seem clumsy, but I
think that the benefits more than compensate for this. It would be a
relatively simple task to write some headers which macro Desk's names to
the old DeskLib names without the prefix.
Also, all variables such as 'event_taskhandle' are now called
'Desk_Event_taskhandle' rather than 'Desk_event_taskhandle'. The
capitalised 'Event' means that the object occupies memory, as opposed to
structure names such as 'Desk_event_pollblock'.
Note that all structure field-names are identical to the DeskLib ones.
Error handling
——————————————
Most functions have been changed to make use of the 'Error2' sublibrary,
which was introduced in DeskLib betas after DeskLib release 2.30.
All (not quite all yet) swi veneers now send any error straight to the
Error2 system. This is done either by calling the non-X form and relying
on the C runtime system to convert any error into a signal which can be
caught by Error2, or calling the X form and then branching to
Desk_Error2_CheckOS if the V flag is set.
The first method is slightly simpler, but doesn't work in SVC mode (the
C runtime system doesn't convert OS errors to a signal in SVC) so is
only used for Wimp SWIs which will always (I think) be called from USR
mode (for example, the task part of module-tasks still run in USR mode).
It would have been possible to put some conditional assembley so that
the non-X form is used for non-module builds of the library, but this is
a lot of hastle, and the branch to the Error2 handling after an X SWI is
only one instruction (it's a macro in 'C:Desk.sh.Macros').
This means that code can use C++-style exception handling (see the
Jump.h and JumpAuto.h files), so you can malloc memory, call library
functions etc etc without worrying about error-return codee after every
function call.
The client application is required to call Desk_Error2_Init_JumpSig() to
initialise the error system.
I think there is a problem in that this will catch SIGSTACK - the error
handler is compiled with standard stack-checking, so an infinite loop
will result...
Note that you are forced to use the Error2-system when using Desk - any
error not caught (eg because you didn't call Desk_Error2_Init_JumpSig())
will halt the program.
Directory structure
———————————————————
Everything is in a 'Desk' directory, rather than an application
directory, which is intended to be put into C$Path. Hence headers are
included with '#include "Desk.Wimp.h"'. This means that Desk is a more
conventional library, rather than setting its own system variables etc
which is rather unnecessary I think.
Source code is /within/ the .o directory, which may seem a little
strange. It is also within a '!DeskSrc' application directory, so the
code can be compiled with complete filenames using the
'Desk_Sources$Dir' system variable, which can aid debugging.
Building the various versions of Desk is done with my freeware 'Makatic'
tools, which cuts down the number of obscure script files that were in
DeskLib.
Changes to sublibraries
———————————————————————
The file 'Desk.History' contains a list of all changes since DeskLib
2.30. Due to extreme lack of time, many changes since DeskLib betas have
not been documented particularly well.
Other things
————————————
All code that used to call DeskLib's 'SWI' function now uses Acorn's
'_swi'. One reason is that SWI would have to be modified (albeit fairly
trivially) to work on the StrongARM. More importantly for me, SWI isn't
ROM-able. Also, I think _swi is a lot easier to use.
I haven't built a SDLS version of Desk. The Jump library has untested
support for the expensions to longjmp required by SDLS.
There are several versions of the library:
C:Desk.o.Desk Normally compiled.
C:Desk.o.Desk_D Compiled with Desk_DEBUG predefined, so
Desk_Debug_Printf statements are active.
C:Desk.o.Desk_M Compiled with cc -zM, for use in module
code.
C:Desk.o.Desk_M_D Compiled with cc -zM and Desk_DEBUG
predefined.
C:Desk.o.Desk_MC Compiled for use with MemCheck, plus
with cc -g, so can be used with DDT.
ToDo
————
Auto-Freeing of resources after errors
Resources have to be explicitly released whenever an error occurs, which
results in code like:
{
void* volatile ptr = NULL;
Desk_Error2_Try {
...
ptr = Desk_DeskMem_Malloc( ...);
...
}
Desk_Error2_Catch {
Desk_DeskMem_Free( ptr);
Desk_Error2_ReThrow();
}
Desk_Error2_EndCatch
...
}
I have found this sort of code to occur very commonly. The problem is
that it is rather longwinded, and the call to setjmp made by
Desk_Error2_Try is probably rather slow (it has to save all registers
etc, and restricts the optimising that the compiler can carry out).
Note that not using Desk_Error2 would still require 'ptr' to be freed in
case of error. One common way of doing this is to use the dreaded goto:
{
void* ptr = NULL;
os_error* e;
ptr = malloc( ...);
if ( !ptr) { e=...; goto error; }
if ( e=Foo( ...), e) goto error;
if ( e=Bar( ...), e) goto error;
...
return NULL;
error:
free( ptr);
return e;
}
so the Desk_Error2 system isn't making code more difficult to write
really.
Anyway, a way to avoid the try..catch blocks would be to make
Desk_DeskMem_Malloc put every malloc block in a singly-linked list, and
make Desk_Error2_Try store the last malloc block. Then when an error
occurrs, Desk_JumpAuto_Throw would automatically free all blocks up to
(and not including) the block registered by the last Desk_Error2_Try.
This scheme could be extended to automatically call fclose() etc. It has
the drawback of adding a one word overhead to every malloc block.
Note that in normal operation, no automatic freeing of blocks would
occur. If some allocated memory was required to be preserved even after
an error occurred, it would have to be allocated using something like
Desk_DeskMem_MallocPermanent() or something.
Make Save library use Export.
Make SDLS version.
Use RCS.
Lots of other things...
Important note
——————————————
Even though I now work for Acorn, Desk has nothing to do with Acorn.
It's status is the same as DeskLib - a freeware library supplied with
all source and no support 8) .
- Julian Smith
jsmith@acorn.co.uk